
import java.net.URL;
import java.util.List;
import java.util.Vector;
import javax.media.opengl.GL;
import mesh.Appearance;
import mesh.Face;
import mesh.Mesh;
import mesh.MeshGeometry;
import mesh.MeshUtils;
import mesh.Scene;
import mesh.Vertex;
import tiger.core.Pass;
import tiger.core.RenderState;
import tiger.core.Window;

/**
 *
 * @author cmolikl
 */
public class MeshDisplay {

    Mesh mesh;
    Appearance app;
    MeshGeometry geometry;
    ImageProcessing imageProcessing;
    VoxelProcessing voxelProcessing;
    
    Vector<Triangle> triangles;
    
    
    public MeshDisplay() {
        geometry = new MeshGeometry();
        imageProcessing = new ImageProcessing();
        voxelProcessing = new VoxelProcessing(imageProcessing.getImages());
        
        voxelProcessing.marchingCubes();
       
        triangles = voxelProcessing.getTriangleList();
        
        app = new Appearance("grey");
        app.setAmbient(0.2f, 0.2f, 0.2f);
        app.setDiffuse(0.6f, 0.6f, 0.6f);
        
        mesh = new Mesh();
        mesh.setName("Lebka");
        mesh.setGeometry(geometry);
        mesh.setAppearance(app);
    }

    public Mesh createMesh(){
        for(int i = 0; i<triangles.size(); i++){
            Vertex v0 = new Vertex(triangles.elementAt(i).vertices[0].x(),
                                   triangles.elementAt(i).vertices[0].y(),
                                   triangles.elementAt(i).vertices[0].z());
            Vertex v1 = new Vertex(triangles.elementAt(i).vertices[1].x(),
                                   triangles.elementAt(i).vertices[1].y(),
                                   triangles.elementAt(i).vertices[1].z());
            Vertex v2 = new Vertex(triangles.elementAt(i).vertices[2].x(),
                                   triangles.elementAt(i).vertices[2].y(),
                                   triangles.elementAt(i).vertices[2].z());
            v0.setNormal(triangles.elementAt(i).normals[0].x(),
                         triangles.elementAt(i).normals[0].y(),
                         triangles.elementAt(i).normals[0].z());
            v1.setNormal(triangles.elementAt(i).normals[1].x(),
                         triangles.elementAt(i).normals[1].y(),
                         triangles.elementAt(i).normals[1].z());
            v2.setNormal(triangles.elementAt(i).normals[2].x(),
                         triangles.elementAt(i).normals[2].y(),
                         triangles.elementAt(i).normals[2].z());
            Face f = new Face(v0, v1, v2);
        
            geometry.add(v0);
            geometry.add(v1);
            geometry.add(v2);
            geometry.add(f);
        }
        return mesh;
    }
    
    public Mesh createMesh(float iso) {
        
        Vertex v11 = new Vertex(0.0, 0.0, 0.0);
        v11.setNormal(0f, 0f, -1f);
        Vertex v12 = new Vertex(1.0, 0.0, 0.0);
        v12.setNormal(0f, 0f, -1f);
        Vertex v13 = new Vertex(0.0, 1.0, 0.0);
        v13.setNormal(0f, 0f, -1f);

        Vertex v21 = new Vertex(0.0, 0.0, 0.0);
        v21.setNormal(-1f, 0f, 0f);
        Vertex v22 = new Vertex(0.0, 1.0, 0.0);
        v22.setNormal(-1f, 0f, 0f);
        Vertex v23 = new Vertex(0.0, 0.0, 1.0);
        v23.setNormal(-1f, 0f, 0f);

        Vertex v31 = new Vertex(0.0, 0.0, 0.0);
        v31.setNormal(0f, -1f, 0f);
        Vertex v32 = new Vertex(0.0, 0.0, 1.0);
        v32.setNormal(0f, -1f, 0f);
        Vertex v33 = new Vertex(1.0, 0.0, 0.0);
        v33.setNormal(0f, -1f, 0f);

        Vertex v41 = new Vertex(1.0, 0.0, 0.0);
        v41.setNormal(1f, 1f, 1f);
        Vertex v42 = new Vertex(0.0, 1.0, 0.0);
        v42.setNormal(1f, 1f, 1f);
        Vertex v43 = new Vertex(0.0, 0.0, 1.0);
        v43.setNormal(1f, 1f, 1f);

        Face f1 = new Face(v11, v13, v12);
        Face f2 = new Face(v21, v23, v22);
        Face f3 = new Face(v31, v33, v32);
        Face f4 = new Face(v41, v42, v43);

        geometry.add(v11);
        geometry.add(v12);
        geometry.add(v13);
        geometry.add(v21);
        geometry.add(v22);
        geometry.add(v23);
        geometry.add(v31);
        geometry.add(v32);
        geometry.add(v33);
        geometry.add(v41);
        geometry.add(v42);
        geometry.add(v43);
        
        geometry.add(f1);
        geometry.add(f2);
        geometry.add(f3);
        geometry.add(f4);

        return mesh;
    }

    public static void main(String[] args) {

        MeshDisplay md = new MeshDisplay();
        Mesh mesh = md.createMesh();

        Scene scene = new Scene();
        scene.addMesh(mesh);
        scene.setBoundingSphere(MeshUtils.getBoundingSphere(mesh));

        RenderState state = new RenderState();
        state.setBuffersToClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        state.enable(GL.GL_DEPTH_TEST);
        state.enable(GL.GL_LIGHTING);
        // Následující řádek způsobí, že se nebudou vykreslovat odvrácené plošky
        //state.enable(GL.GL_CULL_FACE);

        URL vShader = ClassLoader.getSystemResource("Phong.vert");
        URL fShader = ClassLoader.getSystemResource("Phong.frag");
        Pass meshDisplay = new Pass(vShader, fShader);
        meshDisplay.scene = scene;
        meshDisplay.renderState = state;

        Window frame = new Window(scene);
        frame.setEffect(meshDisplay);
        frame.runFastAsPosible = false;
        frame.start();
    }

}
